import React from 'react';
import { Upload, message, Modal } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { createImg, getUploadToken } from '@/services/ant-design-pro/api';

function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = (error) => reject(error);
  });
}

export default class AliyunOSSUpload extends React.Component {
  state = {
    OSSData: {},
    previewVisible: false,
    previewImage: '',
    previewTitle: '',
    fileList: [],
    token: '',
    host: '',
    key: '',
  };

  /**
   * 组件挂载完成后，进行初始化，获取oss配置
   */

  async componentDidMount() {
    await this.init();
  }

  static getDerivedStateFromProps(props, state) {
    if (props.fileList) {
      return {
        fileList: props.fileList,
      };
    } else {
      return { fileList: state.fileList };
    }
  }

  /**
   * 初始化，获取oss上传签名
   */

  init = async () => {
    try {
      const OSSData = await getUploadToken();
      if (OSSData.data && OSSData.data.uploadToken) {
        this.setState({
          token: OSSData.data.uploadToken,
          host: OSSData.data.host,
          key: OSSData.data.key,
        });
      } else {
        message.error('获取token失败请重试');
      }
    } catch (err) {
      message.error('网络出错，请重试');
    }
  };

  /**
   * 文件上传过程中触发的回调，直到上传完成
   */

  onChange = async (e) => {
    const { file, fileList } = e;
    const { status, response } = file;
    if (status === 'done') {
      const host = this.state.host;
      const path = `${host}/${response.key}`;
      file.url = path;
      const params = {
        bind_type: this.props.bindType === 'estate' ? 0 : 1,
        bind_id: +this.props.bindId,
        store: 'oss', // 默认选择server
        path,
      };
      await createImg({ data: params });
    }
    if (this.props.onChange) {
      this.props.onChange({ ...e, file });
    }
    this.setState({ fileList });
  };

  handleCancel = () => this.setState({ previewVisible: false });

  /**
   * 额外的上传参数
   */
  getExtraData = (file) => {
    const { OSSData } = this.state;
    const key = this.state.key + file.name;
    return {
      key: key,
      token: this.state.token,
      OSSAccessKeyId: OSSData.accessid,
      policy: OSSData.policy,
      Signature: OSSData.signature,
    };
  };

  /**
   * 选择文件之后，上传文件之前，执行回调
   */
  beforeUpload = async (file) => {
    const { OSSData } = this.state;
    const expire = OSSData.expire * 1000;
    // 如果签名过期了，重新获取
    if (expire < Date.now()) {
      await this.init();
    }
    return file;
  };

  handlePreview = async (file) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj);
    }
    this.setState({
      previewImage: file.url || file.preview,
      previewVisible: true,
      previewTitle: file.name || file.url.substring(file.url.lastIndexOf('/') + 1),
    });
  };

  render() {
    const { previewVisible, previewImage, fileList, previewTitle } = this.state;
    const { maxCount } = this.props;

    const uploadButton = (
      <div>
        <PlusOutlined />
        <div style={{ marginTop: 8 }}>上传图片</div>
      </div>
    );

    return (
      <>
        <Upload
          name="file"
          fileList={fileList}
          maxCount={maxCount}
          action={`//upload-z2.qiniup.com`}
          listType="picture-card"
          onChange={this.onChange}
          data={this.getExtraData}
          onPreview={this.handlePreview}
          beforeUpload={this.beforeUpload}
          onRemove={this.props.onRemove}
        >
          {fileList.length >= maxCount ? null : uploadButton}
        </Upload>
        <Modal
          visible={previewVisible}
          title={previewTitle}
          footer={null}
          onCancel={this.handleCancel}
        >
          <img alt="example" style={{ width: '100%' }} src={previewImage} />
        </Modal>
      </>
    );
  }
}
